SQL基础教程

您所在的位置:网站首页 group by语句 SQL基础教程

SQL基础教程

2023-04-11 09:15| 来源: 网络整理| 查看: 265

视频教程地址:SQL基础教程-3章3节Having为聚合指定条件 - SQL基础教程 - 西瓜视频 (ixigua.com)

上一节我们学了group by分组,同时提到如果只想查询聚合后的某些数据,使用where是不行的,这就要用到本节学习的Having关键字了,它的作用是按照聚合函数的结果,对聚合后的数据进行筛选过滤。同样,定义都是比较抽象的,下边我们结合示例来深入学习一下。

这一节的实例中用到的表是product,数据如下:

SELECT * FROM product; product_id | product_name | product_type | sale_price | purchase_price | regist_date ------------+--------------+--------------+------------+----------------+------------- 0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-09-01 0003 | 运动T恤衫 | 衣服 | 4000 | 2800 | 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-05 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 0008 | 圆珠笔 | 办公用品 | 100 | | 0002 | 打孔器 | 办公用品 | 880 | 320 | 2009-09-11 0006 | 叉子 | 厨房用具 | 880 | | 2009-09-20 (8 行记录)从一个例子开始

想查询一下商品数量小于4的分类,利用上一节的知识,先使用count(*) 和group by查询出各分类的商品数量。

shop=# SELECT product_type, COUNT(*) FROM product GROUP BY product_type; product_type | count --------------+------- 衣服 | 2 办公用品 | 2 厨房用具 | 4 (3 行记录)

having放在group by子句的后面来过滤count(*):

shop=# SELECT product_type, COUNT(*) FROM product GROUP BY product_type HAVING COUNT(*) < 4; product_type | count --------------+------- 衣服 | 2 办公用品 | 2 (2 行记录)Having语法

having的语法如下:

SELECT expression1, expression2, ... expression_n, aggregate_function (expression) FROM tables [WHERE conditions] GROUP BY expression1, expression2, ... expression_n HAVING condition;

having必须写在group by子句的后面,having后面跟上过滤条件,这个条件必须是聚合函数或group by子句中出现的列名,关于这个内容我们下面会讲到。

总结一下包含having的select语句的书写顺序:

SELECT -> FROM -> WHERE -> GROUP BY -> HAVING

这个顺序不能搞错,搞错就运行不起来了。

Having的一般写法

再来看一个例子,我们想查询一下每类商品的售价均值,并且只想看均价大于500的分类。遇到这类查询,我们的解题思路一般是,先用group by查出全部结果,再写having去过滤这些数据,分两步走,思路会更清晰一些。

第一步,先查出每类商品的均值:

shop=# SELECT product_type, AVG(sale_price) FROM product GROUP BY product_type; product_type | avg --------------+----------------------- 衣服 | 2500.0000000000000000 办公用品 | 490.0000000000000000 厨房用具 | 2890.0000000000000000 (3 行记录)

第二步,再having过滤

shop=# SELECT product_type, AVG(sale_price) AS avg_sale_price FROM product GROUP BY product_type HAVING AVG(sale_price) > 500; product_type | avg_sale_price --------------+----------------------- 衣服 | 2500.0000000000000000 厨房用具 | 2890.0000000000000000 (2 行记录)

这里注意一点,having后面是不可以使用别名avg_sale_price的,这是为什么呢?原因还跟SQL语句的执行顺序有关,SQL的顺序是:

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT

在执行having时,select还没有执行,所以也就没有列的别名呢,当然也就不能使用了。

Having子句构成要素

Having后面只能跟3种类型的子句:常数、聚合函数、group by后面跟的列;

举一个having后跟不是group by的列的例子:

shop=# select product_type, avg(sale_price) as avg_sale_price from product group by product_type having sale_price > 500; 错误: 字段 "product.sale_price" 必须出现在 GROUP BY 子句中或者在聚合函数中使用 第1行...e_price from product group by product_type having sale_price...

sale_price不在group by中,所以就报错了。

那么,having后面跟的聚合函数中是否可以使用其它列呢?

shop=# select product_type, avg(sale_price) as avg_sale_price from product group by product_type having avg(purchase_price) > 500; product_type | avg_sale_price --------------+----------------------- 衣服 | 2500.0000000000000000 厨房用具 | 2890.0000000000000000 (2 行记录)

可以看出是可以的,purchase_price既不在group by中,也不在select中,但仍然可以在having中出现。这又是为什么呢?

这仍然要从SQL执行顺序来解释,在group by分组后,当前的数据仍然是使用where过滤后的所有列,此时执行having,当然每个列也都可以用啦。不过,一般场景,having主要过滤的还是select中的聚合函数。

理解了SQL执行顺序,我们来看一个更复杂的例子:

shop=# SELECT product_type, AVG(sale_price), COUNT(*), AVG(purchase_price) FROM product GROUP BY product_type HAVING AVG(purchase_price) > 500 and AVG(sale_price) > 1000; product_type | avg | count | avg --------------+-----------------------+-------+----------------------- 衣服 | 2500.0000000000000000 | 2 | 1650.0000000000000000 厨房用具 | 2890.0000000000000000 | 4 | 2863.3333333333333333 (2 行记录)

我们就不去管到底查询的是什么了,只用看到:

(1)SELECT 后可以跟任何列的聚合函数;

(2)HAVING后可以跟多个条件;

WHERE和HAVING怎么选

上一部分中提到,HAVING后可以跟group by后的列名,现在做一个查询,查询除衣服外的其它分类的商品数量,先使用HAVING实现:

shop=# SELECT product_type, count(*) FROM product GROUP BY product_type HAVING product_type '衣服'; product_type | count --------------+------- 办公用品 | 2 厨房用具 | 4 (2 行记录)

再使用WHERE来实现:

shop=# SELECT product_type, count(*) FROM product WHERE product_type '衣服' GROUP BY product_type; product_type | count --------------+------- 办公用品 | 2 厨房用具 | 4 (2 行记录)

可以看出,结果都是一样的,那我们要怎么选呢?

先说一下WHERE和HAVING的区别,WHERE过滤的是行,HAVING过滤的是组,两者的场景是不一样的。我们的建议是HAVING后只跟聚合函数,列的条件要放在WHERE中。所以上面这种情况还是要选WHERE来实现。

还有另一个原因就是性能,group by是要做聚合的,聚会就要先进行排序,执行速度是比较慢的,数据量越大就越慢,根据上面提到的SQL执行顺序,WHERE会先执行,经过WHERE过滤后,到执行GROUP BY时,数据量就已经减少很多了,执行起来速度会更快。另外,列上也是可以建索引的,索引是数据库执行速度优化的一个重要手段,在建了索引的列上使用where速度会快很多倍。

视频教程地址

本节视频教程地址:SQL基础教程-3章3节Having为聚合指定条件 - SQL基础教程 - 西瓜视频 (ixigua.com)

【下一节】

知乎个人主页地址:https://www.zhihu.com/people/yu1949



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3